package com.cheetah.start.common.exception;

import cn.dev33.satoken.exception.NotLoginException;
import com.cheetah.start.common.base.result.Result;
import com.cheetah.start.common.plugin.log.ConsoleLog;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 统一异常捕获
 *
 * @author xjhmwj
 * @date 2021/1/8 10:19
 */
@Slf4j
@ControllerAdvice
public class GlobaException {
    @Autowired
    private Ip2regionSearcher regionSearcher;
    @Autowired
    private ConsoleLog consoleLog;

    /**
     * 数据校验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public Result bindException(BindException e, HttpServletRequest request) {
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> list = bindingResult.getAllErrors();
        StringBuilder builder = new StringBuilder();
        list.forEach(x -> {
            FieldError error = (FieldError) x;
            builder.append(error.getDefaultMessage());
            builder.append("<br/>");
        });
        consoleLog.logErrorRequest();
        return Result.failure(builder.toString());
    }


    /**
     * 单个参数异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseBody
    public Result constraintViolationException(ConstraintViolationException e, HttpServletRequest request) {
        consoleLog.logErrorRequest();
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("<br/>"));
        return Result.failure(message);
    }

    /**
     * 请求类型错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public Result httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return Result.failure("请求类型错误");
    }

    /**
     * 项目异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = CheetahException.class)
    @ResponseBody
    public Result cheetahException(CheetahException e  ) {
        consoleLog.logErrorRequest();
        return Result.failure(e.getMessage());
    }


    /**
     * 需要登录异常
     *
     * @param e e
     * @return {@link Result}
     */
    @ExceptionHandler(value = NotLoginException.class)
    public ModelAndView notLoginException(NotLoginException e) {
        log.error("需要登录:[{}]", e.getMessage());
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/login");
        return modelAndView;
    }


    /**
     * 运行异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public Result runtimeException(RuntimeException e) {
        log.error("运行异常:", e);
        consoleLog.logErrorRequest();
        return Result.failure("运行异常");
    }

    /**
     * 异常
     *
     * @param e e
     * @return {@link Result}
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result exception(Exception e) {
        log.error("运行异常:", e);
        consoleLog.logErrorRequest();
        return Result.failure("系统异常");
    }
}


